4
4
.
.
4
4
.
.
6
6
P
P
a
a
t
t
h
h
I
I
n
n
f
f
o
o
[
[
R
R
]
]
This tutorial shows how to use Path View to draw custom shapes.
Path uses a set of drawing methods to define a shape like: lines, curves and arcs.
T
T
r
r
i
i
a
a
n
n
g
g
l
l
e
e
This example shows how to use Path to draw Triangle.
Triangle
struct ContentView : View {
var body : some View {
Path { path in
path.move (to: CGPoint(x: 200, y: 200))
path.addLine(to: CGPoint(x: 400, y: 200))
path.addLine(to: CGPoint(x: 300, y: 300))
path.closeSubpath()
}
.stroke(Color.green, lineWidth: 5)
}
}
Triangle
E
E
x
x
t
t
r
r
a
a
c
c
t
t
i
i
n
n
t
t
o
o
s
s
t
t
r
r
u
u
c
c
t
t
This tutorial shows how to extract your Custom Shape into separate struct which can then be used as built in Shapes.
Extract into struct (With absolute coordinates)
struct ContentView : View {
var body : some View {
MyTriangle()
.stroke(Color.green, lineWidth: 5)
}
}
struct MyTriangle : Shape {
func path(in rect: CGRect) -> Path {
Path { path in
path.move (to: CGPoint(x: 200, y: 200))
path.addLine(to: CGPoint(x: 400, y: 200))
path.addLine(to: CGPoint(x: 300, y: 300))
path.closeSubpath()
}
}
}
We will now rewrite our code so that it doesn't use absolute coordinates.
Instead we want our triangle to take up the whole surface so that we could later adjust he size using .frame().
rect is invisible scratchpad inside which we can draw our triangle and which can get transformed by .frame().
Remove absolute coordinates
struct ContentView : View {
var body : some View {
MySquare()
.stroke(Color.green, lineWidth: 5)
.frame(width: 250, height: 250)
}
}
struct MySquare: Shape {
func path(in rect: CGRect) -> Path {
Path { path in
path.move (to: CGPoint(x: 0, y: 0))
path.addLine(to: CGPoint(x: rect.size.width, y: 0))
path.addLine(to: CGPoint(x: rect.size.width / 2, y: rect.size.height))
path.closeSubpath()
}
}
}
With absolute coordinates Removed absolute coordinates
B
B
é
é
z
z
i
i
e
e
r
r
c
c
u
u
r
r
v
v
e
e
Bézier curve is declared by specifying next point and control point.
Bézier curve
struct ContentView : View {
var body : some View {
ZStack {
//Bézier curve
Path { path in
path.move (to: CGPoint(x: 200, y: 200))
path.addQuadCurve(to: CGPoint(x: 400, y: 200), control: CGPoint(x: 300, y: 10))
}.stroke(Color.green, lineWidth: 5)
//Tangent
Path { path in
path.move (to: CGPoint(x: 200, y: 200))
path.addLine(to: CGPoint(x: 300, y: 10))
}.stroke(Color.black, lineWidth: 1)
//Tangent
Path { path in
path.move (to: CGPoint(x: 400, y: 200))
path.addLine(to: CGPoint(x: 300, y: 10))
}.stroke(Color.black, lineWidth: 1)
}
}
}
control: CGPoint(x: 300, y: 10) control: CGPoint(x: 300, y: 100)
(200, 200)
(400, 200)
(300, 10)
control point
control point
(300, 100)
(200, 200)
(400, 200)